#ifndef MONO_EVENT_POLLER_H_
#define MONO_EVENT_POLLER_H_

#include <mono/common/timestamp.h>
#include <mono/event/event_loop.h>
#include <unordered_map>
#include <vector>


struct epoll_event;

namespace mono {

class Channel;

class Poller {
public:
    typedef std::vector<Channel*> ChannelList;

    Poller(EventLoop* loop);
    virtual ~Poller();

    /// Polls the I/O events.
    /// Must be called in the loop thread.
    mono::Timestamp poll(int timeoutMs, ChannelList* activeChannels);

    /// Changes the interested I/O events.
    /// Must be called in the loop thread.
    void updateChannel(Channel* channel);

    /// Remove the channel, when it destructs.
    /// Must be called in the loop thread.
    void removeChannel(Channel* channel);

    bool hasChannel(Channel* channel) const;

    void assertInLoopThread() const
    {
        _ownerLoop->assertInLoopThread();
    }

protected:
    typedef std::unordered_map<int, Channel*> ChannelMap;
    ChannelMap _channels;

private:
    static const int kInitEventListSize = 16;

    void fillActiveChannels(int numEvents,
                            ChannelList* activeChannels) const;
    void update(int operation, Channel* channel);

    typedef std::vector<struct epoll_event> EventList;

    EventLoop       *_ownerLoop;
    int              _epollfd;
    EventList        _events;
    
};

}
#endif
